package net.goutalk.glcs.module.erpModel.caseErpUnit.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.yulichang.base.MPJBaseServiceImpl;
import net.goutalk.glcs.common.enums.YesOrNoEnum;
import net.goutalk.glcs.common.model.result.R;
import net.goutalk.glcs.common.page.PageOutput;
import net.goutalk.glcs.module.erpModel.caseErpUnit.dto.AddCaseErpUnitConvertDetailDto;
import net.goutalk.glcs.module.erpModel.caseErpUnit.dto.AddCaseErpUnitConvertDto;
import net.goutalk.glcs.module.erpModel.caseErpUnit.dto.CaseErpUnitConvertDto;
import net.goutalk.glcs.module.erpModel.caseErpUnit.dto.UpdateCaseErpUnitConvertDto;
import net.goutalk.glcs.module.erpModel.caseErpUnit.entity.CaseErpUnit;
import net.goutalk.glcs.module.erpModel.caseErpUnit.entity.CaseErpUnitConvert;
import net.goutalk.glcs.module.erpModel.caseErpUnit.entity.CaseErpUnitConvertDetail;
import net.goutalk.glcs.module.erpModel.caseErpUnit.entity.CaseErpUnitType;
import net.goutalk.glcs.module.erpModel.caseErpUnit.mapper.CaseErpUnitConvertMapper;
import net.goutalk.glcs.module.erpModel.caseErpUnit.service.ICaseErpUnitConvertDetailService;
import net.goutalk.glcs.module.erpModel.caseErpUnit.service.ICaseErpUnitConvertService;
import net.goutalk.glcs.module.erpModel.caseErpUnit.service.ICaseErpUnitService;
import net.goutalk.glcs.module.erpModel.caseErpUnit.service.ICaseErpUnitTypeService;
import net.goutalk.glcs.module.erpModel.caseErpUnit.vo.CaseErpUnitConvertVo;
import net.goutalk.glcs.module.erpModel.caseErpUnit.vo.UnitDetailListVo;
import net.goutalk.glcs.module.erpModel.caseErpUnit.vo.UnitVo;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
@AllArgsConstructor
public class CaseErpUnitConvertServiceImpl extends MPJBaseServiceImpl<CaseErpUnitConvertMapper, CaseErpUnitConvert> implements ICaseErpUnitConvertService {
    private final ICaseErpUnitService caseErpUnitService;

    private final ICaseErpUnitTypeService caseErpUnitTypeService;

    private final ICaseErpUnitConvertDetailService caseErpUnitConvertDetailService;

    @Override
    public PageOutput<CaseErpUnitConvertVo> getPageList(CaseErpUnitConvertDto dto) {
        List<CaseErpUnitConvertVo> result = new ArrayList<>();

        List<CaseErpUnitConvertDetail> caseErpUnitConvertDetailList = caseErpUnitConvertDetailService.list(Wrappers.<CaseErpUnitConvertDetail>query().lambda()
                .orderByDesc(CaseErpUnitConvertDetail::getCreateDate));

        List<CaseErpUnitConvert> caseErpUnitConvertList = this.list();

        List<CaseErpUnit> caseErpUnitList = caseErpUnitService.list();

        List<CaseErpUnitType> caseErpUnitTypeList = caseErpUnitTypeService.list();

        List<Long> unitTypeIdList = caseErpUnitConvertList.stream().map(CaseErpUnitConvert::getUnitTypeId).collect(Collectors.toList()).stream().distinct().collect(Collectors.toList());

        for (Long unitTypeId : unitTypeIdList) {
            CaseErpUnitConvertVo vo = new CaseErpUnitConvertVo();
            String unitTypeName = caseErpUnitTypeList.stream().filter(x -> x.getId().equals(unitTypeId)).findFirst().orElse(new CaseErpUnitType()).getName();
            vo.setUnitTypeId(unitTypeId);
            vo.setUnitTypeName(unitTypeName);
            vo.setState(YesOrNoEnum.YES.getCode());
            //使用单位类型获取单位换算的主键id
            CaseErpUnitConvert caseErpUnitConvert = caseErpUnitConvertList.stream().filter(x -> x.getUnitTypeId().equals(unitTypeId)).findFirst().orElse(new CaseErpUnitConvert());
            vo.setId(caseErpUnitConvert.getId());
            //获取对应单位换算明细表的数据
            List<CaseErpUnitConvertDetail> caseErpUnitConvertDetails = caseErpUnitConvertDetailList.stream().filter(x -> x.getUnitConvertId().equals(caseErpUnitConvert.getId())).collect(Collectors.toList());
            if (caseErpUnitConvertDetails.size() > 0) {
                String quantity = StringPool.EMPTY;
                for (CaseErpUnitConvertDetail caseErpUnitConvertDetail : caseErpUnitConvertDetails) {
                    String baseUnitName = caseErpUnitList.stream().filter(x -> x.getId().equals(caseErpUnitConvertDetail.getBaseUnitId())).findFirst().orElse(new CaseErpUnit()).getName();
                    if(ObjectUtil.isNotEmpty(caseErpUnitConvertDetail.getShiftUnitId())){
                        String shiftUnitName = caseErpUnitList.stream().filter(x -> x.getId().equals(caseErpUnitConvertDetail.getShiftUnitId())).findFirst().orElse(new CaseErpUnit()).getName();
                        String bigDecimal = caseErpUnitConvertDetail.getConvertNumber().stripTrailingZeros().toPlainString();
                        if (StrUtil.isNotBlank(quantity)) {
                            quantity = quantity + ";" + 1 + baseUnitName + "=" + bigDecimal + shiftUnitName;
                        } else {
                            quantity = 1 + baseUnitName + "=" + bigDecimal + shiftUnitName;
                        }
                    }
                    vo.setStandardName(baseUnitName);
                }
                vo.setQuantity(quantity);
            }
            result.add(vo);
        }
        //根据单位类型进行搜索
        if (ObjectUtil.isNotEmpty(dto.getUnitTypeId())) {
            result = result.stream().filter(x -> x.getUnitTypeId().equals(dto.getUnitTypeId())).collect(Collectors.toList());
        }

        PageOutput<CaseErpUnitConvertVo> output = new PageOutput<>();
        output.setCurrentPage(dto.getLimit());
        output.setPageSize(dto.getSize());
        output.setTotal(unitTypeIdList.size());
        output.setList(result);
        return output;
    }

    @Override
    public Boolean add(AddCaseErpUnitConvertDto dto) {
        //新增单位换算表数据
        CaseErpUnitConvert caseErpUnitConvert = new CaseErpUnitConvert();
        caseErpUnitConvert.setUnitTypeId(dto.getUnitTypeId());
        this.save(caseErpUnitConvert);

        if (CollectionUtil.isNotEmpty(dto.getAddCaseErpUnitConvertDetailDtoList())) {
            //新增单位换算明细表数据
            List<AddCaseErpUnitConvertDetailDto> addCaseErpUnitConvertDetailDtoList = dto.getAddCaseErpUnitConvertDetailDtoList();
            List<CaseErpUnitConvertDetail> caseErpUnitConvertDetailList = new ArrayList<>();
            for (AddCaseErpUnitConvertDetailDto addCaseErpUnitConvertDetailDto : addCaseErpUnitConvertDetailDtoList) {
                CaseErpUnitConvertDetail caseErpUnitConvertDetail = new CaseErpUnitConvertDetail();
                caseErpUnitConvertDetail.setUnitConvertId(caseErpUnitConvert.getId());
                caseErpUnitConvertDetail.setBaseUnitId(dto.getBaseUnitId());
                caseErpUnitConvertDetail.setShiftUnitId(addCaseErpUnitConvertDetailDto.getShiftUnitId());
                caseErpUnitConvertDetail.setConvertNumber(addCaseErpUnitConvertDetailDto.getConvertNumber());
                caseErpUnitConvertDetailList.add(caseErpUnitConvertDetail);
            }
            caseErpUnitConvertDetailService.saveBatch(caseErpUnitConvertDetailList);
        } else {
            CaseErpUnitConvertDetail caseErpUnitConvertDetail = new CaseErpUnitConvertDetail();
            caseErpUnitConvertDetail.setUnitConvertId(caseErpUnitConvert.getId());
            caseErpUnitConvertDetail.setBaseUnitId(dto.getBaseUnitId());
            caseErpUnitConvertDetailService.save(caseErpUnitConvertDetail);
        }
        return true;
    }

    @Override
    public Boolean edit(UpdateCaseErpUnitConvertDto dto) {
        //先删除再新增
        this.removeById(dto.getId());
        caseErpUnitConvertDetailService.remove(Wrappers.<CaseErpUnitConvertDetail>query().lambda().eq(CaseErpUnitConvertDetail::getUnitConvertId, dto.getId()));
        //新增单位换算表数据
        CaseErpUnitConvert caseErpUnitConvert = new CaseErpUnitConvert();
        caseErpUnitConvert.setUnitTypeId(dto.getUnitTypeId());
        this.save(caseErpUnitConvert);

        if (CollectionUtil.isNotEmpty(dto.getAddCaseErpUnitConvertDetailDtoList())) {
            //新增单位换算明细表数据
            List<AddCaseErpUnitConvertDetailDto> addCaseErpUnitConvertDetailDtoList = dto.getAddCaseErpUnitConvertDetailDtoList();
            List<CaseErpUnitConvertDetail> caseErpUnitConvertDetailList = new ArrayList<>();
            for (AddCaseErpUnitConvertDetailDto addCaseErpUnitConvertDetailDto : addCaseErpUnitConvertDetailDtoList) {
                CaseErpUnitConvertDetail caseErpUnitConvertDetail = new CaseErpUnitConvertDetail();
                caseErpUnitConvertDetail.setUnitConvertId(caseErpUnitConvert.getId());
                caseErpUnitConvertDetail.setBaseUnitId(dto.getBaseUnitId());
                caseErpUnitConvertDetail.setShiftUnitId(addCaseErpUnitConvertDetailDto.getShiftUnitId());
                caseErpUnitConvertDetail.setConvertNumber(addCaseErpUnitConvertDetailDto.getConvertNumber());
                caseErpUnitConvertDetailList.add(caseErpUnitConvertDetail);
            }
            caseErpUnitConvertDetailService.saveBatch(caseErpUnitConvertDetailList);
        } else {
            CaseErpUnitConvertDetail caseErpUnitConvertDetail = new CaseErpUnitConvertDetail();
            caseErpUnitConvertDetail.setUnitConvertId(caseErpUnitConvert.getId());
            caseErpUnitConvertDetail.setBaseUnitId(dto.getBaseUnitId());
            caseErpUnitConvertDetailService.save(caseErpUnitConvertDetail);
        }
        return true;
    }

    @Override
    public AddCaseErpUnitConvertDto getInfo(Long id) {
        CaseErpUnitConvert caseErpUnitConvert = this.getById(id);
        if (caseErpUnitConvert == null) {
            R.error("无此单位转换信息");
        }
        List<CaseErpUnitConvertDetail> caseErpUnitConvertDetailList = caseErpUnitConvertDetailService.list(Wrappers.<CaseErpUnitConvertDetail>query().lambda()
                .eq(CaseErpUnitConvertDetail::getUnitConvertId, id)
                .orderByDesc(CaseErpUnitConvertDetail::getCreateDate));
        AddCaseErpUnitConvertDto addCaseErpUnitConvertDto = new AddCaseErpUnitConvertDto();
        addCaseErpUnitConvertDto.setUnitTypeId(caseErpUnitConvert.getUnitTypeId());
        if (CollectionUtil.isNotEmpty(caseErpUnitConvertDetailList)) {
            addCaseErpUnitConvertDto.setBaseUnitId(caseErpUnitConvertDetailList.get(0).getBaseUnitId());
            List<AddCaseErpUnitConvertDetailDto> addCaseErpUnitConvertDetailDtoList = new ArrayList<>();
            for (CaseErpUnitConvertDetail caseErpUnitConvertDetail : caseErpUnitConvertDetailList) {
                AddCaseErpUnitConvertDetailDto addCaseErpUnitConvertDetailDto = new AddCaseErpUnitConvertDetailDto();
                addCaseErpUnitConvertDetailDto.setConvertNumber(caseErpUnitConvertDetail.getConvertNumber());
                addCaseErpUnitConvertDetailDto.setShiftUnitId(caseErpUnitConvertDetail.getShiftUnitId());
                addCaseErpUnitConvertDetailDtoList.add(addCaseErpUnitConvertDetailDto);
            }
            addCaseErpUnitConvertDto.setAddCaseErpUnitConvertDetailDtoList(addCaseErpUnitConvertDetailDtoList);
        }
        return addCaseErpUnitConvertDto;
    }

    @Override
    public List<UnitDetailListVo> listAll() {
        List<CaseErpUnit> caseErpUnitList = caseErpUnitService.list();
        List<CaseErpUnitType> caseErpUnitTypeList = caseErpUnitTypeService.list();
        List<CaseErpUnitConvertDetail> caseErpUnitConvertDetailList = caseErpUnitConvertDetailService.list();
        List<UnitDetailListVo> unitDetailListVos = new ArrayList<>();
        List<Long> unitTypeIdList = this.list().stream().map(CaseErpUnitConvert::getUnitTypeId).collect(Collectors.toList());

        caseErpUnitTypeList= caseErpUnitTypeList.stream().filter(x -> unitTypeIdList.contains(x.getId()) && x.getState()==YesOrNoEnum.YES.getCode() ).collect(Collectors.toList());

        for (CaseErpUnitType caseErpUnitType : caseErpUnitTypeList) {
            List<UnitVo> unitVo=new ArrayList<>();

            List<CaseErpUnit> caseErpUnitList1 = caseErpUnitList.stream().filter(x -> ObjectUtil.isNotEmpty(x.getUnitTypeId()) && x.getUnitTypeId().equals(caseErpUnitType.getId())
                    && ObjectUtil.isNotEmpty(x.getState()) && x.getState() == YesOrNoEnum.YES.getCode()).collect(Collectors.toList());

            UnitDetailListVo unitDetailListVo=new UnitDetailListVo();
            unitDetailListVo.setId(caseErpUnitType.getId());
            unitDetailListVo.setTypeName(caseErpUnitType.getName());
            unitDetailListVo.setState(caseErpUnitType.getState());

            for (CaseErpUnitConvertDetail caseErpUnitConvertDetail : caseErpUnitConvertDetailList) {
                if (ObjectUtil.isNotEmpty(caseErpUnitConvertDetail.getBaseUnitId())){
                    CaseErpUnit caseErpUnitBase = caseErpUnitList1.stream().filter(x -> x.getId().equals(caseErpUnitConvertDetail.getBaseUnitId()))
                            .findFirst().orElse(new CaseErpUnit());
                    if (ObjectUtil.isNotEmpty(caseErpUnitBase) && StrUtil.isNotBlank(caseErpUnitBase.getName())){
                        UnitVo unitVo2=new UnitVo();
                        unitVo2.setNumber(new BigDecimal("1"));
                        unitVo2.setIsStandard(1);
                        unitVo2.setUnitName(caseErpUnitBase.getName());
                        unitVo2.setSymbol(caseErpUnitBase.getSymbol());
                        unitVo.add(unitVo2);
                        unitDetailListVo.setUnitVo(unitVo);
                        unitDetailListVos.add(unitDetailListVo);
                    }
                }
                if (ObjectUtil.isNotEmpty(caseErpUnitConvertDetail.getShiftUnitId())){
                    CaseErpUnit caseErpUnitShift = caseErpUnitList1.stream().filter(x -> x.getId().equals(caseErpUnitConvertDetail.getShiftUnitId()))
                            .findFirst().orElse(new CaseErpUnit());
                    if (ObjectUtil.isNotEmpty(caseErpUnitShift) && StrUtil.isNotBlank(caseErpUnitShift.getName())){
                        UnitVo unitVo1=new UnitVo();
                        unitVo1.setNumber(caseErpUnitConvertDetail.getConvertNumber());
                        unitVo1.setIsStandard(caseErpUnitShift.getIsStandard());
                        unitVo1.setUnitName(caseErpUnitShift.getName());
                        unitVo1.setSymbol(caseErpUnitShift.getSymbol());
                        unitVo.add(unitVo1);
                        unitDetailListVo.setUnitVo(unitVo);
                        unitDetailListVos.add(unitDetailListVo);
                    }
                }
            }
        }

        //去重操作
        if (CollectionUtil.isNotEmpty(unitDetailListVos)){
            for (UnitDetailListVo unitDetailListVo : unitDetailListVos) {
                if (ObjectUtil.isNotEmpty(unitDetailListVo.getUnitVo())){
                    //基准单位去重操作
                    UnitVo unitVo = unitDetailListVo.getUnitVo().stream().filter(x -> x.getIsStandard() == YesOrNoEnum.YES.getCode()).findFirst().orElse(new UnitVo());
                    List<UnitVo> unitVoList = unitDetailListVo.getUnitVo().stream().filter(x -> ObjectUtil.isNotEmpty(x.getIsStandard())
                            && x.getIsStandard() == YesOrNoEnum.NO.getCode()).collect(Collectors.toList());
                    unitVoList.add(unitVo);
                    unitDetailListVo.setUnitVo(unitVoList);
                }
            }
            //集合去重操作
            unitDetailListVos = unitDetailListVos.stream().distinct().collect(Collectors.toList());
        }

        return unitDetailListVos;
    }

}
